<template>
  <div class="container" ref="container">
    <img
      :src="imageSrc"
      :style="{
        transform: `translate(${position.x}px, ${position.y}px)  scale(${localScale})`
      }"
      @mousedown="startDrag"
      @wheel.prevent="handleZoom"
      class="draggable-img"
      draggable="false"
    />

    <!-- top: position.y + 'px', left: position.x + 'px', -->
  </div>
</template>
<script lang="ts" setup>
import { ref, reactive, toRefs, onMounted, onBeforeMount, watch, computed } from 'vue'
const state = reactive({
  position: { x: 0, y: 0 },
  isDragging: false,
  startPos: { x: 0, y: 0 }
})
const { position, isDragging, startPos } = toRefs(state)
const props = defineProps({
  imageSrc: {
    type: String,
    default: ''
  },
  scale: {
    type: Number,
    default: 1
  }
})
const imageSrc = ref()

const imgRef = ref()
const localScale = ref(0)
const container = ref()

onBeforeMount(() => {
  imageSrc.value = props.imageSrc
  localScale.value = props.scale
})

const emit = defineEmits(['update:scale'])

// 计算属性：双向绑定scale
const computedScale = computed({
  get() {
    return localScale.value
  },
  set(value) {
    // 限制缩放范围
    localScale.value = Math.max(0.5, Math.min(10, value))
    // 触发更新父组件的scale
    emit('update:scale', localScale.value)
  }
})

// 监听props.scale变化，同步到localScale
watch(
  () => props.scale,
  (newVal) => {
    localScale.value = newVal
  }
)

// 初始化localScale
onMounted(() => {
  localScale.value = props.scale
})
const startDrag = (e: any) => {
  console.log(e, '被拖拽元素')
  imgRef.value = e.target // 缓存图片元素
  isDragging.value = true

  startPos.value = {
    x: e.clientX - position.value.x,
    y: e.clientY - position.value.y
  }
  window.addEventListener('mousemove', drag)
  window.addEventListener('mouseup', stopDrag)
  window.addEventListener('blur', stopDrag)
}

const drag = (e: any) => {
  // 边界检测

  const containerInof = container.value.getBoundingClientRect()

  if (!imgRef.value) return // 确保有图片引用

  if (
    e.clientX < containerInof.left ||
    e.clientX > containerInof.right ||
    e.clientY < containerInof.top ||
    e.clientY > containerInof.bottom
  ) {
    stopDrag()
    return
  }

  const maxX = containerInof.width - imgRef.value.width
  const maxY = containerInof.height - imgRef.value.height

  position.value.x = Math.max(0, Math.min(e.clientX - startPos.value.x, maxX))
  position.value.y = Math.max(0, Math.min(e.clientY - startPos.value.y, maxY))
  console.log(containerInof.width, 'containerInof', e.target.width, '元素的宽度')
}
const stopDrag = () => {
  console.log('停止拖拽，失去焦点')
  isDragging.value = false
  window.removeEventListener('mousemove', drag)
  window.removeEventListener('mouseup', stopDrag)
  window.removeEventListener('blur', stopDrag)
}

const handleZoom = (e: WheelEvent) => {
  // 计算缩放比例
  const scaleFactor = 1.05
  let newScale =
    e.deltaY < 0 ? computedScale.value * scaleFactor : computedScale.value / scaleFactor

  // 限制缩放范围：0.5倍到10倍
  const MAX_SCALE = 100
  const MIN_SCALE = 0.5

  // 标记是否达到缩放边界
  const isAtMaxScale = newScale >= MAX_SCALE
  const isAtMinScale = newScale <= MIN_SCALE

  // 强制将缩放值限制在范围内
  if (isAtMaxScale) {
    newScale = MAX_SCALE
  } else if (isAtMinScale) {
    newScale = MIN_SCALE
  }

  // 如果缩放值未变化（已达边界），则完全跳过后续操作
  if (newScale === computedScale.value) return

  // 更新缩放值
  computedScale.value = newScale
}
</script>

<style lang="scss">
.container {
  position: relative;
  width: 100%;
  height: calc(100vh - 140px);
  overflow: hidden;
  border: 1px solid #ccc;
}
.draggable-img {
  position: absolute;
  cursor: move;
  user-select: none;
}
</style>
